
/*****************************************************************
* ģ �� �� :
* �� �� �� : vdma.h
* ����ļ� :
* ��    �� :
* ��    �� : Xsky
* ��    �� : V0.1
* -------------------------------------------------------------
* �޸ļ�¼ :
* ��  ��         �汾        �޸���      �޸�����
* Dec 28, 2017     v0.1        Xsky        ����
*****************************************************************/

#include <bits/types.h>
#include <bits/stdint-intn.h>
#include <bits/stdint-uintn.h>
#pragma once
#ifndef SRC_VDMA_H_
#define SRC_VDMA_H_

#if __linux__
#include <pthread.h>
#include <semaphore.h>
#endif

#ifdef __cplusplus
extern "C"
{
#endif
/****************************/

/* Register offsets */
#define OFFSET_PARK_PTR_REG                     0x28
#define OFFSET_VERSION                          0x2c

#define OFFSET_VDMA_MM2S_CONTROL_REGISTER       0x00
#define OFFSET_VDMA_MM2S_STATUS_REGISTER        0x04
#define OFFSET_VDMA_MM2S_VSIZE                  0x50
#define OFFSET_VDMA_MM2S_HSIZE                  0x54
#define OFFSET_VDMA_MM2S_FRMDLY_STRIDE          0x58
#define OFFSET_VDMA_MM2S_FRAMEBUFFER1           0x5c
#define OFFSET_VDMA_MM2S_FRAMEBUFFER2           0x60
#define OFFSET_VDMA_MM2S_FRAMEBUFFER3           0x64
#define OFFSET_VDMA_MM2S_FRAMEBUFFER4           0x68

#define OFFSET_VDMA_S2MM_CONTROL_REGISTER       0x30
#define OFFSET_VDMA_S2MM_STATUS_REGISTER        0x34
#define OFFSET_VDMA_S2MM_IRQ_MASK               0x3c
#define OFFSET_VDMA_S2MM_REG_INDEX              0x44
#define OFFSET_VDMA_S2MM_VSIZE                  0xa0
#define OFFSET_VDMA_S2MM_HSIZE                  0xa4
#define OFFSET_VDMA_S2MM_FRMDLY_STRIDE          0xa8
#define OFFSET_VDMA_S2MM_FRAMEBUFFER1           0xac
#define OFFSET_VDMA_S2MM_FRAMEBUFFER2           0xb0
#define OFFSET_VDMA_S2MM_FRAMEBUFFER3           0xb4
#define OFFSET_VDMA_S2MM_FRAMEBUFFER4           0xb8

/* S2MM and MM2S control register flags */
#define VDMA_CONTROL_REGISTER_START                     0x00000001
#define VDMA_CONTROL_REGISTER_CIRCULAR_PARK             0x00000002
#define VDMA_CONTROL_REGISTER_RESET                     0x00000004
#define VDMA_CONTROL_REGISTER_GENLOCK_ENABLE            0x00000008
#define VDMA_CONTROL_REGISTER_FrameCntEn                0x00000010
#define VDMA_CONTROL_REGISTER_INTERNAL_GENLOCK          0x00000080
#define VDMA_CONTROL_REGISTER_WrPntr                    0x00000f00
#define VDMA_CONTROL_REGISTER_FrmCtn_IrqEn              0x00001000
#define VDMA_CONTROL_REGISTER_DlyCnt_IrqEn              0x00002000
#define VDMA_CONTROL_REGISTER_ERR_IrqEn                 0x00004000
#define VDMA_CONTROL_REGISTER_Repeat_En                 0x00008000
#define VDMA_CONTROL_REGISTER_InterruptFrameCount       0x00ff0000
#define VDMA_CONTROL_REGISTER_IRQDelayCount             0xff000000

/* S2MM status register */
#define VDMA_STATUS_REGISTER_HALTED                     0x00000001  // Read-only
#define VDMA_STATUS_REGISTER_VDMAInternalError          0x00000010  // Read or write-clear
#define VDMA_STATUS_REGISTER_VDMASlaveError             0x00000020  // Read-only
#define VDMA_STATUS_REGISTER_VDMADecodeError            0x00000040  // Read-only
#define VDMA_STATUS_REGISTER_StartOfFrameEarlyError     0x00000080  // Read-only
#define VDMA_STATUS_REGISTER_EndOfLineEarlyError        0x00000100  // Read-only
#define VDMA_STATUS_REGISTER_StartOfFrameLateError      0x00000800  // Read-only
#define VDMA_STATUS_REGISTER_FrameCountInterrupt        0x00001000  // Read-only
#define VDMA_STATUS_REGISTER_DelayCountInterrupt        0x00002000  // Read-only
#define VDMA_STATUS_REGISTER_ErrorInterrupt             0x00004000  // Read-only
#define VDMA_STATUS_REGISTER_EndOfLineLateError         0x00008000  // Read-only
#define VDMA_STATUS_REGISTER_FrameCount                 0x00ff0000  // Read-only
#define VDMA_STATUS_REGISTER_DelayCount                 0xff000000  // Read-only



#define CAM_HSIZE  				(1920)
#define CAM_VSIZE  				(1080)
#define CAM_PIXELLENGTH			(2)


typedef struct
{
	unsigned int baseAddr;
	int vdmaHandler;
	int width;
	int height;
	int pixelLength;
	int fbLength;
	unsigned int* vdmaVirtualAddress;
	unsigned char* fb1VirtualAddress;
	unsigned char* fb1PhysicalAddress;
	unsigned char* fb2VirtualAddress;
	unsigned char* fb2PhysicalAddress;
	unsigned char* fb3VirtualAddress;
	unsigned char* fb3PhysicalAddress;

	// ���������
	int32_t     used;
	uint32_t*	bufStatusVAddress;	// buffer״̬/���Ƶ�ַ
	int32_t 	uio_fd;
	sem_t		sem;
	uint32_t	flags;
	uint32_t	index;
	uint32_t	index1;
	uint16_t	value;
	uint16_t	value1;

#if __linux__
	pthread_mutex_t lock;
#endif
} vdma_handle;


int vdma_setup(vdma_handle *handle, unsigned int baseAddr, 
			   int width, int height, int pixelLength, 
			   unsigned int fb1Addr, unsigned int fb2Addr, unsigned int fb3Addr);
void vdma_halt(void);
void vdma_start_triple_buffering(vdma_handle *handle);
unsigned int vdma_get(vdma_handle *handle, int num);
void vdma_set(vdma_handle *handle, int num, unsigned int val);

void vdma_status_dump(int status);
void vdma_s2mm_status_dump(vdma_handle *handle);
void vdma_mm2s_status_dump(vdma_handle *handle);

int vdma_running(vdma_handle *handle);
int vdma_idle(vdma_handle *handle);


int  vdma_init(void);
int32_t write_to_file(const char *file, void *pdata, int32_t size);


/****************************/
#ifdef __cplusplus
}
#endif

#endif /* SRC_VDMA_H_ */
